<html>
<meta http-equiv="Content-Type" 	content="text/html;charset=utf-8"/>
<script type="text/javascript" src="../js/jquery/jquery.js"></script>
<script>
/*
 * uploadobj-> uploadmanger -> uploadfactory -> upload
 */
var Upload = function(uploadType) {
    this.uploadType = uploadType;
}

/* 删除文件（内部状态） */
Upload.prototype.delFile = function(id) {
    uploadManger.setExternalState(id, this);    // 把当前id对应的外部状态都组装到共享对象中
    // 大于3000k提示
    if(this.fileSize < 3000) {
        return this.dom.parentNode.removeChild(this.dom);
    }
    if(window.confirm("确定要删除文件吗？" + this.fileName)) {
        return this.dom.parentNode.removeChild(this.dom);
    }
}

/** 工厂对象实例化 
 *  如果某种内部状态的共享对象已经被创建过，那么直接返回这个对象
 *  否则，创建一个新的对象
 */
var UploadFactory = (function() {
    var createdFlyWeightObjs = {};
    return {
        create: function(uploadType) {
            if(createdFlyWeightObjs[uploadType]) {
                return createdFlyWeightObjs[uploadType];
            }
            return createdFlyWeightObjs[uploadType] = new Upload(uploadType);
        }
    };
})();

/* 管理器封装外部状态 */
var uploadManger = (function() {
    var uploadDatabase = {};

    return {
        add: function(id, uploadType, fileName, fileSize) {
            var flyWeightObj = UploadFactory.create(uploadType);
            var dom = document.createElement('div');
            dom.innerHTML = "<span>filename:" + fileName + ",filesize:" + fileSize +"</span>"
                          + "<button class='delFile'>delete</button>";

            dom.querySelector(".delFile").onclick = function() {
                flyWeightObj.delFile(id);
            };
//             console.log(window.document.body)
//             console.log(document.documentElement.body)

            document.body.appendChild(dom);

            uploadDatabase[id] = {
                fileName: fileName,
                fileSize: fileSize,
                dom: dom
            };

            return flyWeightObj;
        },
        setExternalState: function(id, flyWeightObj) {
        	console.log("this-flyWeightObj:"+flyWeightObj)
            var uploadData = uploadDatabase[id];
            for(var i in uploadData) {
                // 直接改变形参（新思路！！）
                flyWeightObj[i] = uploadData[i];
            }
        }
    };
})();
$(document).ready(function(){	
/*触发上传动作*/
var id = 0;
//window.startUpload = function(uploadType, files) {
var startUpload = function(uploadType, files) {
    for(var i=0,file; file = files[i++];) {
        var uploadObj = uploadManger.add(++id, uploadType, file.fileName, file.fileSize);
    }
};

/* 测试 */
new startUpload("plugin", [
    {
        fileName: '1.txt',
        fileSize: 1000
    },{
        fileName: '2.txt',
        fileSize: 3000
    },{
        fileName: '3.txt',
        fileSize: 5000
    }
]);
new startUpload("flash", [
    {
        fileName: '4.txt',
        fileSize: 1000
    },{
        fileName: '5.txt',
        fileSize: 3000
    },{
        fileName: '6.txt',
        fileSize: 5000
    }
]);
	
});
</script>
<body>
	<p>
		<br />
	</p>
	<h1
		style="box-sizing: border-box; margin: 30px 0px 0px; font-size: 22px; font-family: &amp; amp; quot; Microsoft Yahei&amp;amp; quot;; font-weight: 400; line-height: 1.5em; color: rgb(48, 87, 134); padding: 0px; text-align: center; white-space: normal; widows: 1; background: none;">JavaScript设计模式--享元模式</h1>
	<p class="author"
		style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px; padding: 30px 0px 0px; line-height: 1.5em; font-size: 14px; color: rgb(85, 146, 193); text-align: center; font-family: &amp; amp; quot; Microsoft Yahei&amp;amp; quot;; white-space: normal; widows: 1;">
		<span style="box-sizing: border-box; color: rgb(153, 153, 153);">作者：</span><a
			href="http://my.csdn.net/ligang2585116" target="_blank"
			style="box-sizing: border-box; color: rgb(85, 146, 193); text-decoration: none; background: transparent;">ligang2585116</a>
	</p>
	<div class="divtexts"
		style="box-sizing: border-box; margin: 30px 0px 0px; padding: 0px; line-height: 1.8; font-size: 14px; color: rgb(86, 95, 105); position: relative; overflow: hidden; font-family: &amp; amp; quot; Microsoft Yahei&amp;amp; quot;; white-space: normal; widows: 1; max-height: 100%;">
		<h2 id="一定义"
			style="box-sizing: border-box; font-family: Helvetica,&amp; amp; quot; Tahoma , Arial&amp;amp; quot; , sans-serif; font-weight: 400; line-height: 1.5em; color: rgb(51, 51, 51); margin: 0px 0px 5px; font-size: 18px; padding: 0px; background: none;">一、定义</h2>
		<p
			style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0.5em; padding: 0px; line-height: 2;">
			<span style="box-sizing: border-box;">享元（flyweight）模式是一种用于性能优化的模式，核心是运用共享技术来有效支持大量细刻度的对象。</span>&nbsp;<br
				style="box-sizing: border-box;" />在JavaScript中，浏览器特别是移动端的浏览器分配的内存并不算多，如何节省内存就成了一个非常有意义的事情。&nbsp;<br
				style="box-sizing: border-box;" /> <span
				style="box-sizing: border-box;">享元模式是一种用时间换空间的优化模式</span>
		</p>
		<blockquote
			style="box-sizing: border-box; padding: 0px; margin: 0px; border-left-width: 5px; border-left-style: solid; border-left-color: rgb(238, 238, 238); line-height: 1.5em;">
			<p
				style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0.5em; padding: 0px; line-height: 2;">内衣工厂有100种男士内衣、100中女士内衣，要求给每种内衣拍照。如果不使用享元模式则需要200个塑料模特；使用享元模式，只需要男女各1个模特。</p>
		</blockquote>
		<h2 id="二什么场景下使用享元模式"
			style="box-sizing: border-box; font-family: Helvetica,&amp; amp; quot; Tahoma , Arial&amp;amp; quot; , sans-serif; font-weight: 400; line-height: 1.5em; color: rgb(51, 51, 51); margin: 0px 0px 5px; font-size: 18px; padding: 0px; background: none;">二、什么场景下使用享元模式？</h2>
		<p
			style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0.5em; padding: 0px; line-height: 2;">
			（1）程序中使用大量的相似对象，造成很大的内存开销&nbsp;<br style="box-sizing: border-box;" />（2）对象的大多数状态都可以变为外部状态，剥离外部状态之后，可以用相对较少的共享对象取代大量对象
		</p>
		<h2 id="三如何应用享元模式"
			style="box-sizing: border-box; font-family: Helvetica,&amp; amp; quot; Tahoma , Arial&amp;amp; quot; , sans-serif; font-weight: 400; line-height: 1.5em; color: rgb(51, 51, 51); margin: 0px 0px 5px; font-size: 18px; padding: 0px; background: none;">三、如何应用享元模式？</h2>
		<p
			style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0.5em; padding: 0px; line-height: 2;">
			第一种是应用在数据层上，主要是应用在内存里大量相似的对象上；&nbsp;<br
				style="box-sizing: border-box;" />第二种是应用在DOM层上，享元可以用在中央事件管理器上用来避免给父容器里的每个子元素都附加事件句柄。
		</p>
		<p
			style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0.5em; padding: 0px; line-height: 2;">
			享元模式要求将对象的属性分为<span style="box-sizing: border-box;">内部状态</span>和<span
				style="box-sizing: border-box;">外部状态</span>。&nbsp;<br
				style="box-sizing: border-box;" />内部状态独立于具体的场景，通常不会改变，可以被一些对象共享；&nbsp;<br
				style="box-sizing: border-box;" />外部状态取决于具体的场景，并根据场景而变化，外部状态不能被共享。
		</p>
		<p
			style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0.5em; padding: 0px; line-height: 2;">享元模式中常出现工厂模式，Flyweight的内部状态是用来共享的，Flyweight
			factory负责维护一个Flyweight pool(模式池)来存放内部状态的对象。</p>
		<p
			style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0.5em; padding: 0px; line-height: 2;">
			<span style="box-sizing: border-box;">缺点</span>：对象数量少的情况，可能会增大系统的开销，实现的复杂度较大！
		</p>
		<h2 id="四示例文件上传"
			style="box-sizing: border-box; font-family: Helvetica,&amp; amp; quot; Tahoma , Arial&amp;amp; quot; , sans-serif; font-weight: 400; line-height: 1.5em; color: rgb(51, 51, 51); margin: 0px 0px 5px; font-size: 18px; padding: 0px; background: none;">四、示例：文件上传</h2>
	</div>
	<p>
		<br />
	</p>
</body>


</html>